Я хотел бы изменить порядок строк в текстовом файле (или stdin), сохраняя содержимое каждой строки.
Итак, то есть, начиная с:
foo
bar
baz
Я хочу закончить с
baz
bar
foo
Существует ли для этого стандартная утилита командной строки UNIX?
Также стоит упомянуть: tac
(the, ahem, reverse от cat
). Часть coreutils.
tac a.txt > b.txt
Там известные sed трюки:
# reverse order of lines (emulates "tac")
# bug/feature in HHsed v1.5 causes blank lines to be deleted
sed '1!G;h;$!d' # method 1
sed -n '1!G;h;$p' # method 2
(Объяснение: добавьте незапущенную строку для хранения буфера, строки подкачки и удерживающего буфера, распечатайте строку в конце)
Альтернативно (с более быстрым выполнением) из однострочных awk:
awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file*
Если вы не можете вспомнить это,
perl -e 'print reverse <>'
В системе с утилитами GNU другие ответы проще, но не во всем мире есть GNU/Linux...
tail -r
и tac.
Если вы оказались в vim
, используйте
:g/^/m0
$ (tac 2> /dev/null || tail -r)
Попробуйте tac
, который работает в Linux, и если это не сработает, используйте tail -r
, который работает на BSD и OSX.
tac myfile.txt
- что мне не хватает?
tail -r
если tac
недоступен. tac
не соответствует POSIX. Ни один не tail -r
. Все еще не надежно, но это повышает шансы на то, что все работает.
Попробуйте выполнить следующую команду:
grep -n "" myfile.txt | sort -r -n | gawk -F : "{ print $2 }"
sed 's/^[0-9]*://g'
Просто Bash:) (4.0 +)
function print_reversed {
readarray -t LINES
for (( I = ${#LINES[@]}; I; )); do
printf '%s\n' "${LINES[--I]}"
done
}
print_reversed < file
-nenenenenenene
и -nenenenenenene
причину, по которой люди рекомендуют всегда использовать printf '%s\n'
вместо echo
.
Самый простой способ - использовать команду tac
. tac
является cat
обратным.
Пример:
$ cat order.txt
roger shah
armin van buuren
fpga vhdl arduino c++ java gridgain
$ tac order.txt > inverted_file.txt
$ cat inverted_file.txt
fpga vhdl arduino c++ java gridgain
armin van buuren
roger shah
tac <file_name>
Пример:
$ cat file1.txt
1
2
3
4
5
$ tac file1.txt
5
4
3
2
1
Мне очень нравится ответ "tail -r", но мой любимый ответ gawk -....
gawk '{ L[n++] = $0 }
END { while(n--)
print L[n] }' file
mawk
на Ubuntu 14.04 LTS - работает, поэтому это не специфично для GNU awk. +1
Для решения перекрестных ОС (например, OSX, Linux), которые могут использовать tac
внутри оболочки script, используйте homebrew, как упоминалось выше, а затем просто псевдоним tac, например:
brew install coreutils
echo "alias tac='gtac'" >> ~/.bash_aliases (or wherever you load aliases)
source ~/.bash_aliases
tac myfile.txt
Лучшее решение:
tail -n20 file.txt | tac
ИЗМЕНИТЬ следующее генерирует беспорядочно отсортированный список чисел от 1 до 10:
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') **...**
где точки заменяются фактической командой, которая меняет список
нолики
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') \
<(tac)
python: используя [:: - 1] в sys.stdin
seq 1 10 | sort -R | tee /tmp/lst |cat <(cat /tmp/lst) <(echo '-------') \
<(python -c "import sys; print(''.join(([line for line in sys.stdin])[::-1]))")
У меня был тот же вопрос, но я также хотел, чтобы первая строка (заголовок) оставалась на вершине. Поэтому мне нужно было использовать мощность awk
cat dax-weekly.csv | awk '1 { last = NR; line[last] = $0; } END { print line[1]; for (i = last; i > 1; i--) { print line[i]; } }'
PS также работает в cygwin или gitbash
1\n20\n19...2\n
а не к 20\n19...\2\n1\n
.
sort -r < filename
или
rev < filename
sort -r
работает, только если входные данные уже отсортированы, что здесь не так. rev
переворачивает символы в строке, но сохраняет порядок строк, что тоже не то, о чем просил Скотти. Так что этот ответ на самом деле не является ответом вообще.
perl -e 'print reverse <>'
но, вероятно, это применимо и к другим методам).