locate
не "в реальном времени" :он сканирует файловую систему и запоминает файлы и местоположения в своей внутренней базе данных. Вот что происходит с вами здесь, когда вы бежите:
/usr/bin/youtube-dl
Вам предоставлено устаревшее значение местоположения этого файла, так как база данных еще (не была )обновлена. Вы можете форсировать это с помощью:
slocate -u
все подробности:https://ss64.com/bash/locate.html
awk '
FNR == NR { data[++n] = $0; next }
{
data[2] = $1; data[6] = $2; data[7] = $3;
outname = sprintf("out%d", FNR) # or: outname = "out" FNR
for (i = 1; i <= n; ++i)
print data[i] >outname
close(outname)
}' file1 file2
Сначала читается file1
, затем file2
.
При чтенииfile1
(блока FNR == NR
)единственное, что делает код awk
— это сохраняет каждую строку в массиве data
.
При чтении file2
код берет каждое из трех полей в строке этого файла и присваивает им индексы в data
, соответствующие строкам, которые вы хотите изменить в file1
.
Строки, хранящиеся в data
, затем печатаются в имя файла, составленное путем взятия номера текущей строки в file2
и добавления к нему строки out
.
close(outname)
действительно необходим только в том случае, если вы используете awk
, который не является GNU awk
, и вы записываете в большее количество файлов, чем ограничение на дескрипторы открытых файлов (больше, чем ulimit -n
] возвращает минус три для стандартных потоков ).
Тестирование:
$ tree
.
|-- file1
`-- file2
0 directory, 2 files
$ awk '
FNR == NR { data[++n] = $0; next }
{
data[2] = $1; data[6] = $2; data[7] = $3;
outname = sprintf("out%d", FNR)
for (i = 1; i <= n; ++i)
print data[i] >outname
close(outname)
}' file1 file2
$ tree
.
|-- file1
|-- file2
|-- out1
|-- out2
`-- out3
0 directory, 5 files
$ paste out[123]
w w w
1 6 5
y y y
G G G
7 7 7
1 6 6
1 7 5
$ cat tst.awk
BEGIN {
split("2 6 7",tmp)
for (fldNr in tmp) {
map[tmp[fldNr]] = fldNr
}
}
NR==FNR {
rows[++numRows] = $i
next
}
{
out = "out" FNR
for (rowNr=1; rowNr<=numRows; rowNr++) {
print (rowNr in map ? $(map[rowNr]) : rows[rowNr]) > out
}
close(out)
}
$ awk -f tst.awk file1 file2
$ head out?
==> out1 <==
w
1
y
G
7
1
1
==> out2 <==
w
6
y
G
7
6
7
==> out3 <==
w
5
y
G
7
6
5
Используя GNU sed мы получаем выходные данные в файлах _0/1/2 для каждой строки файла2.
tmpf=$(mktemp) i=0
while read -ra a <&3
do
printf '%s\n' "${a[@]}" > "$tmpf"
sed -ne "
$(printf '%dba\n' 2 6 7)
p;d;:a
R $tmpf
" file1 > "out_$i"
(( i++ ))
done 3< file2