Итерации по каждой строке ls -l output

120

Я хочу перебрать каждую строку в выводе: ls -l /some/dir/*

Прямо сейчас пытаюсь: for x in $(ls -l $1); do echo $x; done

Однако это перебирает каждый элемент в строке отдельно, поэтому я получаю:

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:07
File1

-r--r-----
1
ivanevf
eng
1074
Apr
22
13:17
File2

Но я хочу перебирать каждую строку в целом. Как я могу это сделать?

Иван
источник
1
Всегда заключайте переменные (и выходные данные команд) в кавычки, если у вас нет особых причин не делать этого.
Гленн Джекман

Ответы:

247

Установите IFS на новую строку, например:

IFS='
'
for x in `ls -l $1`; do echo $x; done

Если вы не хотите устанавливать IFS постоянно, поместите вокруг него дополнительную оболочку:

(IFS='
'
for x in `ls -l $1`; do echo $x; done)

Или используйте while | читайте вместо этого:

ls -l $1 | while read x; do echo $x; done

Еще один вариант, который запускает while / read на том же уровне оболочки:

while read x; do echo $x; done << EOF
$(ls -l $1)
EOF
Рэнди Проктор
источник
12
Будьте осторожны при подключении
1
Что здесь делает 1 доллар? Мне нужно использовать это в сценарии, который я пишу, который принимает аргументы. 1 доллар отбрасывает вещи. Что я могу положить туда вместо 1 доллара, чтобы получить тот же эффект? Я бы хотел использовать второе решение.
noob-in-need
@ noob-in-need Замени его любым каталогом, который вы хотите перечислить
vpzomtrrfrt
1
Возможно, вы захотите это сделать, read -rиначе bash удалит неэкранированные обратные косые черты из данных.
Брайан Гордон
6

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

 ls -l | awk '{print $9, $5}'

.. в моей системе печатает имя и размер каждого элемента в каталоге.

Адам Холмберг
источник
3

Как уже упоминалось, для этого подходит awk. Если вы не хотите использовать awk, вместо анализа вывода «ls -l» построчно, вы можете перебрать все файлы и выполнить «ls -l» для каждого отдельного файла следующим образом:

for x in * ; do echo `ls -ld $x` ; done
Axel
источник
3

Вы также можете попробовать findкоманду. Если вам нужны файлы только в текущем каталоге:

find . -d 1 -prune -ls

Выполнить команду для каждого из них?

find . -d 1 -prune -exec echo {} \;

Считать строки, но только в файлах?

find . -d 1 -prune -type f -exec wc -l {} \;

Дэвид Коски
источник
найти не работает. Я часто получаю странные сообщения об ошибках. он хочет помочь мне, когда командная строка полностью верна, и кажется, что как только он начнет это делать, он не остановится до следующей перезагрузки МОЖЕТ БЫТЬ. Иногда ошибки кажутся случайными по своей природе. не знаю, как сообщить об ошибке.
Джим Майклс,
1

Утилита read (1) вместе с перенаправлением вывода команды ls (1) сделает то, что вы хотите.

Стив Эммерсон
источник
-1

Итак, почему никто не предложил просто использовать опции, устраняющие части, которые он не хочет обрабатывать.

В современном Debian вы просто получаете свой файл с помощью:

ls --format=single-column 

Более того, вам не нужно обращать внимание на то, в каком каталоге вы его запускаете, если вы используете полный каталог:

ls --format=single-column /root/dir/starting/point/to/target/dir/

Эту последнюю команду я использую выше и получаю следующий результат:

bot@dev:~/downloaded/Daily# ls --format=single-column /home/bot/downloaded/Daily/*.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141119_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141120_IENT1.txt.gz
/home/bot/downloaded/Daily/Liq_DailyManifest_V3_US_20141121_IENT1.txt.gz
BradChesney79
источник