Объединить вывод двух команд в системе unix
Мне нужно объединить вывод двух команд.
Например:
Если я ввешу ls -l && file *
, он даст мне
-rw-rw-r-- 1 user user 1356 2012-01-21 07:45 string.c
-rwxrwxr-x 1 user user 7298 2012-01-21 07:32 string_out
-rw-rw-r-- 1 user user 777 2012-01-18 21:44 test
string.c: ASCII C program text, with CRLF line terminators
string_out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
test: POSIX shell script text executable
но я хочу:
-rw-rw-r-- 1 user user 1356 2012-01-21 07:45 string.c string.c: ASCII C program text, with CRLF line terminators
-rwxrwxr-x 1 user user 7298 2012-01-21 07:32 string_out string_out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
-rw-rw-r-- 1 user user 777 2012-01-18 21:44 test test: POSIX shell script text executable
Любые предложения, как это сделать?
Ответы
Ответ 1
Shiplu имеет приятное простое решение, в bash вы можете сделать это без использования переменных:
for x in *; do
echo "$(ls -dl $x) $(file $x)"
done;
Или:
for x in *; do echo "$(ls -dl $x) $(file $x)"; done;
В bash, $(cmd)
выводит результат cmd
и помещает его в командную строку, что очень полезно для таких ситуаций.
Форма $()
может быть менее подвержена ошибкам, чем использование backticks (`cmd`), поскольку она безопасно располагается:
echo $(ls -l $(which bash))
С обратными выводами вы должны умножать escape-элементы, например, кавычки
Ответ 2
paste
является вашим другом здесь. Использование bash замены процесса:
paste <(ls -l | sed 1d) <(file *)
edit: добавлена команда sed для удаления первой строки вывода ls ( "total: xx" )
Ответ 3
Для этого вы можете использовать команду join
, но это может быть сложно сделать все в одной командной строке. Если вы создаете два файла с выходом каждой команды, это довольно просто. Возможно, вам придется немного массировать вывод (например, удалить конечный :
на выходе file
).
Ответ 4
Вам нужен цикл
for x in *;
do
ls=`ls -dl $x`
c=`file $x`
echo "$ls $c"
done;
В моем Cygwin нет команды file
. Поэтому я сделал это с помощью wc
. Их формат вывода почти такой же.
$ for x in *; do ls=`ls -l $x`; c=`wc -c $x`; echo "$ls : $c"; done;
-rwxr-xr-x 1 shiplu None 18460 Dec 23 16:27 a.exe : 18460 a.exe
-rw-r--r-- 1 shiplu None 340 Dec 23 16:27 tok.c : 340 tok.c
Ответ 5
Использование awk
:
awk '
NR==FNR{a[$9":"]=$0;next}
($1 in a){printf("%-60s\t%-s\n",a[$1],$0)}' <(ls -l) <(file *)
Использование цикла while
(аналогично @Shiplu и @Kyle, но используя while loop
с field descriptors
:
while read list && read type <&3; do
echo "$list $type";
done < <(tail +2 <(ls -l)) 3< <(file *)