для каждого с массивом с несколькими элементами

В сценарии отсутствует awk:

awk 'BEGIN{FS=OFS="|"} NR==FNR{$1="";++a[$0];next} {field1=$1;$1=""; if ( !(a[$0]) ) {$1=field1;print $0} }' \
/home/path/a.txt  /home/path/b.txt >  /home/path/c.txt

Вероятно, в первой строке сценария также должно быть #!/bin/sh.

В качестве альтернативы вы можете преобразовать скрипт в правильный awk скрипт:

#!/usr/bin/awk -f

BEGIN {FS = OFS = "|"} 

NR==FNR { $1="";++a[$0]; next }

{
  field1 = $1;
  $1 = ""; 
  if ( !(a[$0]) ) {
     $1 = field1;
     print $0;
  }
}

... и затем запустить его, например, с помощью

$ ./bb.awk /home/path/a.txt /home/path/b.txt >/home/path/c.txt
0
11.01.2017, 22:58
5 ответов

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

pairs=( "name1,url1" "name2,url2" "name3,url3" )

for pair in "${pairs[@]}"; do
    #Create an array in itself, of the two values.
    tmpArr=(`echo $pair | tr ',' ' '`)

    #Then either use Array Indexing on the array ie. 
    #Or place the offsets in their own variables. ie Run=${tmpArr[0] ...;
    command ${tmpArr[0]} ${tmpArr[1]}
done

Устраняет необходимость во временных файлах, никакой реальной очистки не требуется, если они используются внутри сценарий, который изначально использует Sha-Bang или делает его локальным в функции, как я и делал большую часть своих сценариев, сохраняя синтаксис как можно ближе к "C". Я также придерживаюсь моего девиза bash: «Если вы хотите это сделать, значит, кто-то уже делал это раньше и сделал модуль, так что не выполняйте эту работу заново ...»

0
28.01.2020, 02:16

Вначале я обратил внимание на такую ​​сложную вещь, как ассоциативные массивы.
Затем я понял, что это можно сделать так же просто, как показано ниже, учитывая, что у вас столько же имен, сколько URL:

root@debian:a=( "name1,url1" "name2,url2" "name3,url3" );while IFS="," \ 
read -r name url;do echo "command $name $url";done<<<$(printf '%s\n' "${a[@]}")
command name1 url1
command name2 url2
command name3 url3

Все, что вам нужно, это хранить имена и URL-адреса в одном массиве (в моем test) вместе, через запятую.

1
28.01.2020, 02:16

Возможно, вам подойдет простой сценарий bash:

pairs=( "name1,url1" "name2,url2" "name3,url3" )

for pair in "${pairs[@]}"; do
    IFS=, read name url <<<"${pair}"
    printf "%s %s\n" "${name}" "${url}"
    command "${name}" "${url}"
done
0
28.01.2020, 02:16

bash довольно ограничен на этом фронте. Вы можете попробовать другие оболочки.

С zsh (вы уже используете синтаксис zsh , поскольку вы не указали свои переменные в команде $ NAME $ URL ):

for name url (
  name1 url1
  name2 url2
  name3 url3
) command $name $url

С bash или другой оболочкой POSIX вы можете сделать:

while IFS=, read <&3 -r name url; do
  {
    command "$name" "$url"
  } 3<&-
done 3<< "EOF"
name1,url1
name2,url2
name3,url3
EOF

Это означает, что значения не могут содержать запятые или символы новой строки.

Последние версии bash также поддерживают ассоциативные массивы, используя синтаксис, больше похожий на синтаксис ksh93, чем на zsh . Итак, если имена уникальны, вы можете сделать:

typeset -A pairs
pairs=(
  [name1]=url1
  [name2]=url2
  [name3]=url3
)
for name in "${!pairs[@]}"; do
  url=${pairs[$name]}
  command "$name" "$url"
done

Это также будет работать в ksh93 . Помните, что правила цитирования между ними немного различаются. В zsh синтаксис определения ассоциативного массива более простой, и применяются обычные правила цитирования:

pairs=(name1 url1 name2 url2 name3 url3)

Которые вы можете поместить в несколько строк:

pairs=(
  name1 url1
  name2 url2
  name3 url3
)

Остерегайтесь, однако, порядок не сохраняется и что Ассоциативные массивы bash не поддерживают пустой ключ.

ksh93 поддерживает многомерные массивы, поэтому вы можете:

pairs=((name1 url1) (name2 url2) (name3 url3))
for ((i = 0; i < ${#pairs[@]}; i++)); do
  name=${pairs[i][o]} url=${pairs[i][1]}
  command "$name" "$url"
done
3
28.01.2020, 02:16

Вы можете создать здесь-документ, который записывается во временный файл и затем обрабатывается. Временный файл будет автоматически удален, поэтому ручная очистка не требуется.

#!/bin/bash
mylist=/var/tmp/$$
trap 'rm -f ${mylist}' EXIT
cat << _EOF_ > ${mylist}
name1 url1
name2 url2
name3,url3
_EOF_
while read name url
do
    printf "%s %s\n" ${name} ${url}
done < ${mylist}
1
28.01.2020, 02:16

Теги

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