Если Вы заключили свою команду в кавычки точно как:
find /opt/path -exec setacl -d user:myUser{} ';'
Вы пропускаете решающее пространство:
find /opt/path -exec setacl -d user:myUser {} ';'
Первый вызывает неопределенный (или возможно определенный реализацией) поведение от find
; это могло бы или не могло бы развернуть имя файла когда {}
не находится в аргументе самостоятельно. Но это затем вызывает setacl
команда без имени файла; это комбинирует имя файла с аргументом управления user:myUser
.
Это вряд ли будет корректно, как записано - но я надеюсь, что это - просто опечатка на Вашей записи от Вашей системы до ТАК.
awk '{for(i=NF;i>0;i--)printf "%s ",$i;print ""}' file
Если Вы не будете возражать против Python затем, то эта острота инвертирует порядок разделенных столбцов пространства в каждой строке:
paddy$ cat infile.txt
a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
a e i o u
paddy$ python3 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$
Вышеупомянутые работы с python2.7 также:
paddy$ python2.7 -c 'with open("infile.txt") as f: print("\n".join(" ".join(line.rstrip().split()[::-1]) for line in f))'
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
paddy$
Один способ использовать awk
.
Содержание infile
:
a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
a e i o u
Выполненный после awk
команда:
awk '{
## Variable 'i' will be incremented from first field, variable 'j'
## will be decremented from last field. And their values will be exchanged.
## The loop will end when both values cross themselves.
j = NF;
for ( i = 1; i <= NF; i++ ) {
if ( j - i < 1 ) {
break;
}
temp = $j;
$j = $i;
$i = temp;
j--;
}
print;
}' infile
Со следующим результатом:
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
u o i e a
Вы могли сделать это с маленьким сценарием Python:
#!/usr/bin/env python
# Swaps order of columns in file, writes result to a file.
# usage: program.py input_file output_file
import sys, os
out = []
for line in open(sys.argv[1], 'r'):
fields = line.split()
rev = ' '.join(list(reversed(fields)))
out.append(rev)
f = open(sys.argv[2], 'w')
f.write(os.linesep.join(out))
Это медленно, но это действительно имеет один плюс. Это поддерживает ширину разделителей полей, когда они более широки, чем отдельный символ. FWIW: Если Вы запускаете этот скрипт дважды, результат идентичен оригиналу.
Вот сценарий.
awk '{ eix = length($0)
for( fn=NF; fn>0; fn--) { dix=eix
while( substr($0,dix,1) ~ /[ \t]/ ) dix--
printf "%s%s", substr($0,dix+1,eix-dix), $fn
dix-=length($fn); eix=dix }
print substr($0,1,dix)
}' "$file"
Вот сравнения некоторого времени. Тестовый файл содержал 1 строку.
fields fields
10,0000 10,000,000
user11136 {python} | real 0.029s real 3.235s
reversible? no | user 0.032s user 2.008s
| sys 0.000s sys 1.228s
jmp {python} | real 0.078s real 5.045s
reversible? no | user 0.068s user 4.268s
| sys 0.012s sys 0.560s
rush {awk} | real 0.120s real 10.889s
reversible? no | user 0.116s user 8.641s
| sys 0.008s sys 2.252s
petero {awk} | real 0.319s real 35.750s
reversible? yes | user 0.304s user 33.090s
| sys 0.016s sys 2.660s
Можно использовать tac
просто необходимо транспонировать вход прежде и после. Это может быть сделано с калькулятором электронной таблицы sc
и его кореш psc
:
< infile psc -S -r | sc -W% - | tac | psc -S -r | sc -W% - > outfile
Как замечено здесь.
Это работает лучше всего, когда все столбцы заполнены.
infile
a b c d e f g h i j k l
1 2 3 4 5 6 7 8 9 10 11 12
A B C D E F G H I J K L
outfile
l k j i h g f e d c b a
12 11 10 9 8 7 6 5 4 3 2 1
L K J I H G F E D C B A
Как отмечено PeterO sc
имеет жесткий предел 702 столбцов, так, чтобы был максимальный размер, поддерживаемый этим методом.
1
-> 1.00
. Кроме того, я получаю ошибки для строк больше чем 702 широкие поля. Это, кажется, касаются числового предела 32 768..., но это довольно быстро, как есть.
– Peter.O
27.08.2012, 04:55
-S
к psc
команда должна интерпретировать все как строки. Относительно предела на 702 столбца это - жесткий предел, потому что только к столбцам ZZ поддерживаются (26 + 26 * 26), я добавлю комментарий об этом.
– Thor
27.08.2012, 12:53
Этот конвейер быстрее, чем самый быстрый другой ответ значимым фактором (см. результаты). Это использует tr
и tac
. Это действительно должно использовать 2 байта ASCII (\x00-\x7F), которые не существуют в Ваших данных.
\x00
обычно хороший выбор, как \x01
, но можно использовать любой байт ASCII, который не находится в данных.
В этом примере, ПРОСТРАНСТВЕ и ВКЛАДКЕ как символы разделителей. Разделители могут быть многобайтовыми или единственными. Выходной разделитель является одиночным пробелом.
Вот команда. Имя файла показывает numberof fields
_x number of lines
<"$file" tr ' \t\n' '\0\0\1' |tr -s '\0' '\n' |tac |tr '\n' ' ' |tr '\1' '\n'
Если Вы хотите/нуждаетесь проверить на неиспользованные байты, можно проверить заранее с этим дополнительным awk
сценарий. Полное время, запуская этот дополнительный скрипт, все еще значительно быстрее, чем другие методы (до сих пор :).. Вот сценарий предварительной обработки.
o=($(<"$file" char-ascii-not-in-stream)); x="${o[0]}"; y="${o[1]}"
<"$file" tr ' \t\n' "$x$x$y" |tr -s "$x" '\n' |tac |tr '\n' ' ' | tr '$y' '\n' >"$file".$user
Это - awk сценарий: char-ascii-not-in-stream
#!/usr/bin/awk -f
{c[$0]} END{for(i=0;i<=127;i++) {if(sprintf("%c", i) in c);else {printf "\\%03o ",i}}}
Второй набор времен, для этого сценария, включает char-ascii-not-in-stream
время.
Peter.O {tr,tac,tr} ==== file_10_x10000
real 0m0.013s 0m0.015s
user 0m0.020s 0m0.020s
sys 0m0.008s 0m0.012s
user11136 {python} ===== file_10_x10000
real 0m0.057s
user 0m0.048s
sys 0m0.008s
jmp {python} =========== file_10_x10000
real 0m0.160s
user 0m0.160s
sys 0m0.000s
rush {awk} ============= file_10_x10000
real 0m0.121s
user 0m0.120s
sys 0m0.000s
##############################################
Peter.O {tr,tac,tr} ==== file_1000_x1000
real 0m0.048s 0m0.059s
user 0m0.040s 0m0.040s
sys 0m0.040s 0m0.048s
user11136 {python} ===== file_1000_x1000
real 0m0.158s
user 0m0.136s
sys 0m0.028s
jmp {python} =========== file_1000_x1000
real 0m0.327s
user 0m0.320s
sys 0m0.008s
rush {awk} ============= file_1000_x1000
real 0m0.832s
user 0m0.820s
sys 0m0s012s
##############################################
Peter.O {tr,tac,tr} ==== file_1000000_x50
real 0m5.221s 0m6.458s
user 0m4.208s 0m5.248s
sys 0m2.624s 0m2.396s
user11136 {python} ===== file_1000000_x50
real 0m16.286s
user 0m10.041s
sys 0m5.148s
jmp {python} =========== file_1000000_x50
real 0m22.845s
user 0m20.705s
sys 0m1.140s
rush {awk} ============= file_1000000_x50
real 0m44.793s
user 0m43.583s
sys 0m0.848s
##############################################
Вы также можете сделать это без print f :
awk 'BEGIN{ORS=""} {for(k=NF;k>0;--k) {print $k; if (k==1) print "\n"; else print " "}} ' file