Как я могу распечатать строки из файла назад (не используя “tac”)?

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

konqueror man:(command)

Для оглавления верхнего уровня:

konqueror man:

Функции:

  • При вводе команды, которая имеет соответствие в нескольких разделах, это берет Вас к странице разрешения неоднозначности
  • Это - графическое приложение, таким образом, Вы не должны помнить загадочные сочетания клавиш для навигации по странице
  • Это включает гиперссылки в связанные страницы (включая, "см. также" страницы),
  • Можно открыть связанные страницы на отдельных вкладках
26
29.07.2015, 01:48
11 ответов

Используя sed эмулировать tac:

sed '1!G;h;$!d' ${inputfile}
33
27.01.2020, 19:39
  • 1
    Это - хорошее решение, но некоторое объяснение того, как это работает, будет еще лучше. –  Chen Levy 16.03.2011, 13:19
  • 2
    Это - известное sed острота. См. "36. Обратный порядок строк (эмулируют "tac" команду Unix)". в Известных Остротах Sed, Объясненных для полного объяснения того, как это работает. –  Johnsyweb 16.03.2011, 13:37
  • 3
    Возможно, стоящий замечания: "Эти две остроты на самом деле используют большую память, потому что они удерживают целый файл, содержат буфер в обратном порядке перед распечатыванием его. Избегайте этих острот для больших файлов". –  Mr. Shickadance 17.03.2011, 16:33
  • 4
    Также - все другие ответы (кроме, возможно, использования того sort - существует шанс, он будет использовать временный файл). –  Random832 15.04.2011, 23:39
  • 5
    Обратите внимание, что tac быстрее для регулярных файлов, потому что он читает файл назад. Для каналов это должно сделать то же как другие решения (держите в памяти или во временных файлах), не значительно быстрее - также. –  Stéphane Chazelas 14.09.2012, 08:48

awk '{a[i++]=$0} END {for (j=i-1; j>=0;) print a[j--] }' file.txt

через awk лайнеры

6
27.01.2020, 19:39
  • 1
    более короткий: awk 'a=$0RS a{}END{printf a}' –  ninjalj 18.03.2011, 01:34
  • 2
    @ninjalj: это может быть короче, но это становится чрезвычайно медленным, поскольку размер файла становится больше. Я бросил после ожидания в течение 2 минут 30 секунд. but your first реверс жемчуга <>' это лучший/самый быстрый ответ на странице (мне), в в 10 раз быстрее, чем это awk ответ (все awk anseres о том же, мудром временем) –  Peter.O 06.08.2012, 20:26
  • 3
    Или awk '{a[NR]=$0} END {while (NR) print a[NR--]}' –  Stéphane Chazelas 14.09.2012, 08:41

Когда Вы попросили делать это в ударе, вот решение, которое не использует awk, sed или жемчуг, просто функция удара:

reverse ()
{
    local line
    if IFS= read -r line
    then
        reverse
        printf '%s\n' "$line"
    fi
}

Вывод

echo 'a
b
c
d
' | reverse

d
c
b
a

Как ожидалось.

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

5
27.01.2020, 19:39
  • 1
    Это быстро становится непрактично медленным, когда размер файла увеличивается, по сравнению с даже самым медленным из других ответов, и как Вы предположили, уносит память довольно легко: *колотите рекурсивную функцию..., но интересная идея. Отказ сегментации * –  Peter.O 06.08.2012, 19:55

Можно передать его по каналу через:

awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'

awk префиксы каждая строка с номером строки, сопровождаемым пространством. sort инвертирует порядок строк путем сортировки на первом поле (номер строки) в обратном порядке, числовой стиль. И sed снимает изоляцию с номеров строки.

Следующий пример показывает это в действии:

pax$ echo 'a
b
c
d
e
f
g
h
i
j
k
l' | awk '{print NR" "$0}' | sort -k1 -n -r | sed 's/^[^ ]* //g'

Это производит:

l
k
j
i
h
g
f
e
d
c
b
a
4
27.01.2020, 19:39
  • 1
    Хорошо.Спасибо! Я попробую это. И спасибо за комментарии! –   16.03.2011, 13:04
  • 2
    cat -n действия во многом как awk '{print NR" "$0}' –  Chen Levy 16.03.2011, 13:09
  • 3
    я думаю, что это назвало Schwartzian, преобразовывает, или Профиль decorate-sort-undecorate –  ninjalj 18.03.2011, 01:25
  • 4
    Этот общий подход хорош в том виде дескрипторы с помощью файлов на диске, если задача является слишком большой, чтобы обоснованно сделать в памяти. Это могло бы быть более нежно на памяти хотя при использовании временных файлов между шагами, а не каналами. –  mc0e 10.08.2016, 09:15

В жемчуге:

cat <somefile> | perl -e 'while(<>) { push @a, $_; } foreach (reverse(@a)) { print; }'
1
27.01.2020, 19:39
  • 1
    или короче perl -e 'print reverse<>' –  ninjalj 18.03.2011, 01:21
  • 2
    (На самом деле, существует более короткий, но это действительно ужасно, свидетельствует свою ужасность: perl -pe '$\=$_.$\}{' ) –  ninjalj 18.03.2011, 01:21
  • 3
    @Frederik Deweerdt: Быстро, но это теряет первую строку... ninjalj: reverse<) быстро: хороший! но "действительно ужасный" является чрезвычайно медленным как количество увеличений строк.!!.... –  Peter.O 06.08.2012, 19:41
  • 4
    @Peter. O -n было лишним там, спасибо. –  Frederik Deweerdt 18.08.2012, 02:46
awk '{print NR" "$0}' | sort -nr
-3
27.01.2020, 19:39

С ed :

ed -s infile <<IN
g/^/m0
,p
q
IN

Если вы используете BSD / OSX (и, надеюсь, скоро на GNU / linux также, как это будет POSIX ):

tail -r infile
8
27.01.2020, 19:39

Решение только для BASH

прочитать файл в массиве bash (одна строка = один элемент массива) и распечатать массив в обратный порядок:

i=0 

while read line[$i] ; do
    i=$(($i+1))
done < FILE


for (( i=${#line[@]}-1 ; i>=0 ; i-- )) ; do
    echo ${line[$i]}
done
0
27.01.2020, 19:39

Bash с файлом карты , упомянутым в комментариях к fiximan, и на самом деле, возможно, лучшая версия:

# last [LINES=50]
_last_flush(){ BUF=("${BUF[@]:$(($1-LINES)):$1}"); } # flush the lines, can be slow.
last(){
  local LINES="${1:-10}" BUF
  ((LINES)) || return 2
  mapfile -C _last_flush -c $(( (LINES<5000) ? 5000 : LINES+5 )) BUF
  BUF=("${BUF[@]}") # Make sure the array subscripts make sence, can be slow.
  ((LINES="${#BUF[@]}" > LINES ? LINES : "${#BUF[@]}"))
  for ((i="${#BUF[@]}"; i>"${#BUF[@]}"-LINES; i--)); do echo -n "${BUF[i]}"; done
}

Его производительность в основном сопоставима с решение sed и становится быстрее по мере уменьшения количества запрашиваемых строк.

0
27.01.2020, 19:39
Simple do this with your file to sort the data in reverse order, and it should be unique.

sed -n '1h;1d;G;h;$p'

0
20.08.2021, 13:37

POSIX vi делает это, поэтому также ed или ex.

ви:

:g/^/m0

бывший:

ex -s infile <<EOS
g/^/move0
x
EOS

изд:

ed -s infile <<EOF
g/^/m0
,p
w
EOF

2
20.08.2021, 13:37

Теги

Похожие вопросы