简体   繁体   中英

xargs to pipe the output of ls command

I am running the command

ls *my_file.txt* | xargs vim

The shell throws a warning message:

Vim: Warning: Input is not from a terminal

following that the file is opened. Note there is only one instance of *my_file.txt*. On exiting the file, I see that on each ENTER the prompt is not on the next line but continues on the same line. The characters are not typed on the display but are buffered and executed on subsequent enter. Basically, the display gets awry.

The intent is basically to pipe the searched file_name to vim. So any alternative solutions are welcome.

Use find and exec instead of xargs .

find /search/path/ -type f -name "*my_file.txt*" -exec vim {} \;

You can add more options to find like -depth to restrict traversing recursively, -regex for complex regular expressions for finding files etc.

I'm not entirely certain I understand what you're doing. If you just want to edit all the *my_file.txt* files, use:

vim *my_file.txt*

No need to mess about with find or xargs . The only problem you'll have is if you have so many files of that form that you'll blow the limits of the command line. But, seriously, you probably don't want to be editing that many files anyway.

As per this discussion here , vim is not one of those programs that you can easily play with its standard input and output (at least in vi mode - ex mode may be different).

You can see a similar problem with doing things like:

`vi filename`
$(vi filename)
vi filename </dev/null

Basically, vim is not meant to have its stdin/stdout mucked about with, it's an interactive editor and expects a terminal device. The after-effects that you're seeing are probably either curses or vim itself not cleaning up the stty settings properly.

If you have a more complex command that generates file names for editing, you can use something like:

vim $(arbitrarily_bizarre_command_which_outputs_filenames)

keeping in mind that the output is simple text substitution so won't easily handle files like my list of porn sites.txt (with spaces in them). vim will see that as five different arguments.

"ls my_file.txt* | vim -" (note the dash at the end)

not sure how to do this on bsd though.

"ls my_file.txt* | vim -"

will not work in bash, as vim treats it as the file content rather than the file name.

find /search/path/ -type f -name "*my_file.txt*" -exec vim {} \\;

note that this will edit files one at a time. if you still would like to edit multiple files in different buffers you should still use

ls *my_file.txt* | xargs vim

or

vim $(ls *my_file.txt*)

provided the output fits in command line argument maximum length.

another solution:

ls *my_file.txt*
vim $(!!)

!! will repeat the command that was executed before, $() will insert the command output in the command line.

Careful: Does not work with filenames that contain spaces or other nasty characters.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM