2013-10-10 4 views
1

Я сделал этот сценарийсписок в Баш скрипт оболочки

#!/bin/bash 

liste=`ls -l` 
for i in $liste 
do 
    echo $i 
done 

Проблема в том, я хочу сценарий отображает каждый результат построчно, но она отображает слово в слово:

у меня есть:

my_name 
etud 
4096 
Oct 
8 
10:13 

, и я хочу иметь:

my_name etud 4096 Oct 8 10:13 

Конечная цель скрипта - проанализировать каждую строку; это причина, по которой я хочу восстановить всю линию. Возможно, это не лучшее решение, но я не знаю, как восстановить строки.

+2

возможный дубликат [Как вы обработать вывод команды в оболочке линии построчно?] (Http://stackoverflow.com/questions/3113005/how-do- вы-process-the-output-of-a-command-in-the-shell-line-by-line) –

+0

@federem Почему бы вам не рассказать нам какую _специфическую информацию из строки? Отметка? Размер? Есть лучшие способы получить эти вещи, не связанные с 'ls'. –

ответ

0

Вы можете заменить

echo $i 

с

echo -n "$i " 

эхо -n выходов на консоль без новой строки.

+1

'echo -n' не является стандартом POSIX. 'printf' - безопасный переносимый подход. –

+0

@Charles Duffy, он определен в IOSE Std 1003.1-2001 POSIX. –

+0

@JimBlack Только как расширение XSI. –

0

Другой, чтобы сделать это с помощью цикла в то время как и без трубы:

#!/bin/bash 

while read line 
do 
    echo "line: $line" 
done < <(ls -l) 
+0

Это правильно (за исключением использования 'read' без' -r' - таким образом, интерпретируемые escape-последовательности - и оставляя '' IFS'' по умолчанию - и, таким образом, с завершающим пробелом), если целью является демонстрация чтения из потока. Это неверно, если целью является демонстрация чтения списка файлов (некоторые действительно считают, что 'ls' - правильный способ сделать это!). Было бы хорошо, если бы ответ был более ясным. –

0

Во-первых, я надеюсь, что вы не по-настоящему, используя ls в вашем реальном коде, но только с использованием его в качестве примера. Если вы хотите список файлов, то ls - неправильный инструмент; см. http://mywiki.wooledge.org/ParsingLs.

Во-вторых, современные версии bash имеют встроенную функцию readarray.

Попробуйте это:

readarray -t my_array < <(ls -l) 
for entry in "${my_array[@]}"; do 
    read -a pieces <<<"$entry" 
    printf '<%s> ' "${pieces[@]}"; echo 
done 

Во-первых, он создает массив (называемый my_array) со всеми выходе из командной запущенной.

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

Если вы хотите прочитать строку за раз, а не сразу прочитать весь файл, см. http://mywiki.wooledge.org/BashFAQ/001 («Как я могу прочитать файл (поток данных, переменную) по очереди (и/или поле) ? -по-поле) ")

+1

'<(ls -l)' провалится при тех же обстоятельствах, что и 'ls -l | в то время как читать ... '. – chepner

+0

@chepner Если ваше значение 'ls'-specific, я не верю, что я когда-либо подразумевал что-либо противное - см. Первый абзац моего ответа. (Тем не менее, если вы не считаете, что потеряете какое-либо локальное состояние процесса, связанное с содержимым, которое вы прочитали «сбой», я не могу согласиться с точностью возражения в общем случае, не относящемся к конкретным случаям) –

1

Для начала, мы будем считать, что ни один из ваших имен файлов никогда не содержат символы новой строки:

ls -l | IFS= while read -r line; do 
    echo "$line" 
    # Do whatever else you want with $line 
done 

Если ваши имена файлов может содержать символы перевода строки, все становится сложнее. В этом случае лучше (хотя и медленнее) использовать stat для получения желаемых метаданных из каждого файла отдельно. Проконсультируйтесь с man stat, чтобы узнать о том, как работает ваш местный ассортимент stat, так как он, к сожалению, не очень стандартизирован.

for f in *; do 
    line=$(stat -c "%U %n %s %y" "$f") # One possibility 
    # Work with $line as if it came from ls -l 
done 
+1

Или просто 'for f in *; do ls -l "$ f"; done' – tripleee

+0

Правда. Однако, если вы все равно должны запускать новый процесс для каждого файла, контроль над выходом, который позволяет 'stat', может быть более удобным. (Но да, я просто забыл, что вы можете называть 'ls' для каждого файла.) – chepner

0

Завершение предыдущих ответов с необходимостью хранения списка файлов в переменной.Вы можете сделать это

 
echo -n "$list"|while read -r lin 
do 
echo $lin 
done 
Смежные вопросы