Подтвердить что ты не робот

Как вы отправляете вывод ls в mv?

Я знаю, что вы можете сделать это с помощью find, но есть ли способ отправить вывод ls в mv в командной строке unix?

4b9b3361

Ответ 1

Один из способов заключается в обратном направлении:

mv `ls *.boo` subdir

Изменить: однако это хрупкое и не рекомендуется - см. @lhunath asnwer для подробных объяснений и рекомендаций.

Ответ 2

ls - это инструмент, используемый для отображения некоторых статистических данных о именах файлов в каталоге.

Это не инструмент, который вы должны использовать, чтобы перечислить их и передать их другому инструменту для его использования. Разбор ls - это почти всегда неправильная вещь, и она прослушивается многими способами.

Для подробного документа о плохой синтаксическом анализе ls, который вы должны прочитать действительно, прочитайте, проверьте: http://mywiki.wooledge.org/ParsingLs

Вместо этого вы должны использовать либо globs, либо find, в зависимости от того, что именно вы пытаетесь достичь:

mv * /foo
find . -exec mv {} /foo \;

Основным источником плохого анализа синтаксического анализа ls является то, что ls сбрасывает все имена файлов в одну строку вывода, и нет возможности указать имена файлов отдельно от них. Насколько вам известно, весь вывод ls может быть одним единственным именем файла!

Вторичный источник плохого анализа синтаксического анализа ls происходит от разбитого способа, в котором половина мира использует bash. Они думают, что for волшебно делает то, что они хотели бы сделать, когда они делают что-то вроде:

for file in `ls`  # Never do this!
for file in $(ls) # Exactly the same thing.

for является встроенным bash, который выполняет итерацию по аргументам. И $(ls) выводит результат ls и разделяет его на аргументы везде, где есть spaces, newlines или tabs. В основном это означает, что вы повторяете слова, а не более имена файлов. Хуже того, вы просите bask взять каждое из этих искалеченных имен файлов, а затем обрабатывать их как глобы, которые могут соответствовать именам файлов в текущем каталоге. Поэтому, если у вас есть имя файла, которое содержит слово, которое является глобусом, совпадающим с другими именами файлов в текущем каталоге, это слово исчезнет, ​​и вместо него появятся все соответствующие им имена!

mv `ls` /foo      # Exact same badness as the ''for'' thing.

Ответ 3

Не совсем уверен, чего вы пытаетесь достичь здесь, но здесь есть одна возможность:

Часть "xargs" - важная часть, все остальное только что настроено. Эффект этого заключается в том, чтобы взять все, что "ls" выводит, и добавить к нему расширение ".txt".

$ mkdir xxx  # 
$ cd xxx
$ touch a b c x y z
$ ls
a  b  c  x  y  z
$ ls | xargs -Ifile mv file file.txt
$ ls
a.txt  b.txt  c.txt  x.txt  y.txt  z.txt
$

Нечто подобное может быть достигнуто также:

$ touch a b c x y z
$ for i in `ls`;do mv $i ${i}.txt; done
$ ls
a.txt  b.txt  c.txt  x.txt  y.txt  z.txt
$

Я вроде как второй способ лучше. Я НИКОГДА не помню, как работает xargs, не читая man-страницу или не переходя к моему файлу "cute tricks".

Надеюсь, что это поможет.

Ответ 4

Проверьте find -exec {}, поскольку это может быть лучший вариант, чем ls, но это зависит от того, чего вы пытаетесь достичь.

Ответ 5

Ни один из ответов пока не безопасен для имен файлов с пробелами в них. Попробуйте следующее:

for i in *; do mv "$i" some_dir/; done

Вы можете, конечно, использовать любой шаблон glob, который вам нравится вместо *.

Ответ 6

Вы не должны использовать вывод ls в качестве ввода другой команды. Файлы с пробелами в их именах сложны, так же как и включение escape-последовательностей ANSI, если у вас есть:

alias ls-'ls --color=always'

например.

Всегда используйте find или xargs (с -0) или globbing.

Кроме того, вы не сказали, хотите ли вы переместить файлы или переименовать их. Каждый из них будет обрабатываться по-разному.

edit: добавлено -0 к xargs (спасибо за напоминание)

Ответ 7

Backticks работают хорошо, как и другие. См. Также xargs. И для действительно сложных вещей, подключите его к sed, создайте список команд, которые вы хотите, затем запустите его снова с выходом sed, подключенным к sh.

Вот пример с find, но он отлично работает с ls:

http://github.com/DonBranson/scripts/blob/f09d24629ab6eb3ce509d4d3078818430306b063/jarfinder.sh

Ответ 8

/bin/ls | tr '\n' '\0' | xargs -0 -i% mv % /path/to/destdir/

"Бесполезное использование ls", но должно работать. Указав полный путь к ls (1), вы избегаете столкновений с псевдонимом ls (1), упомянутым в некоторых предыдущих сообщениях. Команда tr (1) вместе с "xargs -0" заставляет команду работать с именами файлов, содержащими (ugh) пробелы. Он не будет работать с именами файлов, содержащих новые строки, но иметь такие имена файлов в файловой системе - это задавать проблемы, поэтому, вероятно, это не будет большой проблемой. Но имена файлов с новыми символами могут существовать, поэтому лучшим решением было бы использовать "find -print0":

find /path/to/srcdir -type f -print0 | xargs -0 -i% mv % dest/

Ответ 9

Просто используйте find или глобусы ваших снарядов!

find . -depth=1 -exec mv {} /tmp/blah/ \;

.. или..

mv * /tmp/blah/

Вам не нужно беспокоиться о цвете в выводе ls или о странности других строк - Linux позволяет в принципе использовать любые символы в имени файла, кроме нулевого байта. Например:

$ touch "blah\new|
> "
$ ls | xargs file
blahnew|:                  cannot open `blahnew|' (No such file or directory)

.. но найти отлично работает:

$ find . -exec file {} \;
./blah\new|
: empty

Ответ 10

Для более сложных случаев (часто в script) использование массива bash для создания списка аргументов может быть очень полезным. Можно создать массив и нажать на него с соответствующей условной логикой. Например:

Следуя рекомендациям @lhunath , чтобы использовать globs или find, нажимайте файлы, соответствующие шаблону glob, в массив:

myargs=()
# don't push if the glob does not match anything
shopt -s nullglob
myargs+=(myfiles*)

Нажимайте файлы, соответствующие найденному массиву: fooobar.com/questions/153002/....

При необходимости добавьте дополнительные аргументы:

myargs+=("Some directory")

Используйте myargs при вызове команды типа mv:

mv "${myargs[@]}"

Обратите внимание на цитирование массива myargs для правильного пропускания элементов массива с пробелами.

Ответ 11

#!/bin/bash

for i in $( ls * );
do
mv $1 /backup/$1
done

else, это решение поиска sybreon, и, как было предложено НЕ, решение зеленого mv ls.

Ответ 12

Вы окружаете ls с помощью кавычек и помещаете его после mv, так что...

mv `ls` somewhere/

Но имейте в виду, что если у любого из ваших имен файлов есть пробелы, они не будут работать очень хорошо.

Также было бы проще просто сделать что-то вроде этого: mv filepattern* somewhere/