Используя GNU find
, xargs
и cp
, это будет копировать 10 файлов за раз:
d="destination_directory..."
s="source_directory..."
find "$s" -type f -print0 | xargs -0rn 10 cp -n -t "$d"
Может быть, что-то вроде этого?
cat file2 | awk '!(1 in f) {if ((getline l < "-") == 1) split(l, f)} $3!=f[3] {print;next} {print l; delete f}' file1 | column -t
Обратите внимание, что сценарий ожидает file1
в качестве аргумента для awk, в то время как ожидает file2
в качестве своего стандартного ввода . Я использовал «бесполезное использование cat», чтобы показать это более явно, но, естественно, вместо этого вы можете предоставить его как перенаправление < file2
. На самом деле вы можете даже вставить имя файла в сам скрипт, например "file2"
вместо "-"
на getline
, но этот способ немного более гибкий.
Также обратите внимание, что два файла должны запускаться "синхронизированно" с точки зрения значений field3 или, возможно, с file2
"перед" file1
, если это целесообразно для вашего варианта использования.
Только сценарий разбит для удобства чтения,и подробно прокомментирован для объяснения:
# Check if our `real_fields` array is not existent.
# NOTE: we use the `<index> in <array>` construct
# in order to force awk treat `real_fields` name as an
# array (instead of as a scalar as it would by default)
# and build it in an empty state
!(1 in real_fields) {
# get the next line (if any) from the "real" file
if ((getline real_line < "-") == 1)
# split that line in separate fields populating
# our `real_fields` array
split(real_line, real_fields)
# awk split function creates an array with numeric
# indexes for each field found as per FS separator
}
# if field3 of the current line of the "reference"
# file does not match the current line of the "real" file..
$3!=real_fields[3] {
# print current line of "reference" file
print
# go reading next line of "reference" file thus
# skipping the final awk pattern
next
}
# final awk pattern, we get here only if the pattern
# above did not match, i.e. if field3 values from both
# files match
{
# print current line of "real" file
print real_line
# delete our real_fields array, thus triggering
# the fetching of the next line of "real" file as
# performed by the first awk pattern
delete real_fields
}
Вам необходимо установить порядок массива, иначе awk -переупорядочит ваши строки.
#!/usr/bin/awk -f
BEGIN {
PROCINFO["sorted_in"] = "@ind_str_asc"
}
NR==FNR {
a[i++,$3]=$0
next
}
{
for (c in a) {
split(c, s, SUBSEP)
if (s[2] == $3) {
print $0
getline
} else {
print a[c]
}
}
}
./script.awk file1 file2