После запуска mdfind... | xargs cp...
код ошибки в $?
совпадает с кодом xargs
, так как это последняя команда в конвейере. xargs
возвращает 123, если какая-либо команда, которую он выполнил, не удалась, но если mdfind
не производит никакого вывода, то xargs
ничего не делает, поэтому он также не завершается ошибкой.
Однако в Bash коды выхода всех команд в последнем конвейере можно найти в переменной массива PIPESTATUS
. Код выхода первой команды ${PIPESTATUS[0]}
и т. д.
$ false | true | xargs false
$ echo "${PIPESTATUS[*]}"
1 0 123
Таким образом, вместо использования $?
, которое дает вам статус выхода xargs
, вы можете использовать ${PIPESTATUS[0]}
, что дает вам статус выхода mdfind
. Или сохраните лот в другую переменную и протестируйте обе.(saved=("${PIPESTATUS[@]}")
)
В качестве альтернативы используйте set -o pipefail
, чтобы $?
давал вам код выхода последней неудачной команды конвейера, если какая-либо из них не работает.(false | true
приведет к $?=1
.)
Я создал образец входного файла, в котором каждая строка состоит из 10 полей с полями 4 и 9, возможно, заключенными в кавычки:
$ cat file
n9sih438,4994fa72322,PMC,here is an unquoted string,10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,here is an unquoted string,2007-07-25
n9sih438,4994fa72322,PMC,"here is a,",string,","within,", quotes.",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,here is an unquoted string,2007-07-25
n9sih438,4994fa72322,PMC,here is an unquoted string,10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is a,",string,","within,", quotes.",2007-07-25
n9sih438,4994fa72322,PMC,"here is a,",string,","within,", quotes.",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is a,",string,","within,", quotes.",2007-07-25
, а затем написал этот скрипт (, используя GNU awk для 3-го аргумента для match()
), чтобы определить, к какому типу входной строки относится каждая из них, а затем соответствующим образом изменить поле в кавычках (s ):
$ cat tst.awk
BEGIN { FS=OFS="," }
{
# The 4th and 9th fields may or may not be quoted so we are looking
# for one of these patterns of fields:
#
# 1,2,3,4,5,6,7,8,9,10 - type A
# 1,2,3,"4",5,6,7,8,9,10 - type B
# 1,2,3,4,5,6,7,8,"9",10 - type C
# 1,2,3,"4",5,6,7,8,"9",10 - type D
#
# If we can determine which type of record we have then we can
# identify the fields.
delete f
if ( match($0,/^(([^",]+,){9}[^",]+)$/,a) ) {
type = "A"
split(a[0],f)
}
else if ( match($0,/^(([^",]+,){3})(".*"),(([^",]+,){5}[^",]+)$/,a) ) {
type = "B"
split(a[1],f)
f[4] = a[3]
split(a[4],tmp)
for (i in tmp) {
f[4+i] = tmp[i]
}
}
else if ( match($0,/^(([^",]+,){8})(".*"),([^",]+)$/,a) ) {
type = "C"
split(a[1],f)
f[9] = a[3]
f[10] = a[4]
}
else if ( match($0,/^(([^",]+,){3})(".*"),(([^",]+,){4})(".*"),([^",]+)$/,a) ) {
type = "D"
split(a[1],f)
f[4] = a[3]
split(a[4],tmp)
for (i in tmp) {
f[4+i] = tmp[i]
}
f[9] = a[6]
f[10] = a[7]
}
else {
type = "Unknown"
split($0,f)
printf "Warning, could not classify file \"%s\", line %d: %s\n", FILENAME, FNR, $0 | "cat>&2"
}
# Uncomment the following lines to see what the above is doing:
#print ORS "################" ORS "Type " type ":\t" $0
#for (i=1; i in f; i++) {
#print i, "<" f[i] ">"
#}
gsub(/^"|"$/,"",f[4])
gsub(/"/,"\"\"",f[4])
f[4] = "\"" f[4] "\""
gsub(/^"|"$/,"",f[9])
gsub(/"/,"\"\"",f[9])
f[9] = "\"" f[9] "\""
$0 = ""
for (i in f) {
$i = f[i]
}
print
}
.
$ awk -f tst.awk file
n9sih438,4994fa72322,PMC,"here is an unquoted string",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is an unquoted string",2007-07-25
n9sih438,4994fa72322,PMC,"here is a,"",string,"",""within,"", quotes.",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is an unquoted string",2007-07-25
n9sih438,4994fa72322,PMC,"here is an unquoted string",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is a,"",string,"",""within,"", quotes.",2007-07-25
n9sih438,4994fa72322,PMC,"here is a,"",string,"",""within,"", quotes.",10.1371/journal.pone.0000645,PMC1920550,17653272,cc-by,"here is a,"",string,"",""within,"", quotes.",2007-07-25
Вывод всегда заключает в кавычки 2 поля, которые могут быть заключены в кавычки во вводе. -Если вам это не нравится, это простая настройка, оставленная в качестве упражнения. Я также использовал более традиционный способ «экранирования» двойной кавычки в CSV, который заключается в ее удвоении. Опять тривиальное изменение, если вы предпочитаете \"
вместо ""
. См.https://stackoverflow.com/questions/45420535/whats-the-most-robust-way-to-efficiently-parse-csv-using-awkдля получения дополнительной информации об использовании awk для CSV и "стандартов" CSV.