найти минимальное и максимальное значения в дочернем файле и связать этот результат с родительским файлом - PullRequest
1 голос
/ 22 февраля 2012

У меня есть входной файл, как показано ниже.

element  materl(local) 
ipt-shl  stress       sig-xx      sig-yy      sig-zz      sig-xy      sig-yz      sig-zx       plastic
       state                                                                                 strain 
1346995-     25
1-  2 elastic   5.9309E-01 -1.0920E-02  0.0000E+00  2.4431E-04  2.3158E-03  1.0608E-03    7.4616E-02
2-  2 elastic   6.1335E-01 -9.1746E-03  0.0000E+00 -4.2870E-04  2.3158E-03  1.0608E-03    7.4089E-02
3-  2 elastic   6.4586E-01 -7.3146E-03  0.0000E+00 -1.2961E-03  2.3158E-03  1.0608E-03    7.3794E-02
4-  2 elastic   6.7056E-01 -1.5564E-03  0.0000E+00 -1.0469E-03  2.3158E-03  1.0608E-03    7.3682E-02
5-  2 elastic   6.7493E-01  7.1420E-03  0.0000E+00  1.7934E-03  2.3158E-03  1.0608E-03    7.3708E-02
6-  2 elastic   6.7828E-01  1.4787E-02  0.0000E+00  5.4871E-03  2.3158E-03  1.0608E-03    7.3825E-02
7-  2 elastic   6.8092E-01  1.9656E-02  0.0000E+00  8.2580E-03  2.3158E-03  1.0608E-03    7.4210E-02
1346996-     25
1-  2 elastic   6.0586E-01 -4.6476E-03  0.0000E+00  9.4464E-03 -1.9585E-03 -5.1396E-03    7.4299E-02
2-  2 elastic   6.2548E-01 -5.1646E-03  0.0000E+00  6.3450E-03 -1.9585E-03 -5.1396E-03    7.4147E-02
3-  2 elastic   6.5631E-01 -5.3780E-03  0.0000E+00  1.1554E-03 -1.9585E-03 -5.1396E-03    7.4000E-02
4-  2 elastic   6.7186E-01 -1.5611E-03  0.0000E+00 -3.7045E-03 -1.9585E-03 -5.1396E-03    7.3999E-02
5-  2 elastic   6.7481E-01  5.1501E-03  0.0000E+00 -7.2939E-03 -1.9585E-03 -5.1396E-03    7.4107E-02
6-  2 elastic   6.7769E-01  1.1733E-02  0.0000E+00 -1.0146E-02 -1.9585E-03 -5.1396E-03    7.4238E-02
7-  2 elastic   6.7946E-01  1.5462E-02  0.0000E+00 -1.1218E-02 -1.9585E-03 -5.1396E-03    7.4362E-02

и т. Д.

То, что я пытаюсь сделать, это выбрать только столбец, находящийся под пластической деформацией, поместить его в другой файл, а затем найти из него минимум и максимум. Проблема в том, что при переходе на другой файл я теряю личность максимум минимума, который находится в верхней части 7 строк, который является номером элемента. Я использовал

awk '{ print $10 }' elout > Plastic.k    # Shifting the required field to another file
sed -i -e '/^$/d' Plastic.k              # removing all the empty lines 
sed  -n '/^[0-9]\{1\}/p' Plastic.k > tt  # removing all lines with the first letter alphasbet. 
mv tt Plastic.k

Теперь я должен найти максимум и минимум в этом файле Plastic.k, а затем найти номер элемента (идентификатор) этого события в файле elout, оригинальном файле.

Есть предложения?

P.S. под идентичностью я подразумеваю 7-значное число в верхней части группы из 7 строк, за которыми следует символ -

Вывод будет иметь вид

min=7.3682E-02 at 1346995-25
max=7.4616E-02 at 1346995-25

Это не будет 1346996-25, так как у него нет ни минимума, ни максимума в поле 10. У меня есть такие данные из входного файла и я хочу получить вывод в выходном файле.

Если этот формат ввода немного изменился, как показано ниже, ответ от Потонга не работает. Я много пытался понять, но не смог. Новый вход выглядит следующим образом.

Это как то же самое.

element  materl(local)   
ipt-shl  stress       sig-xx      sig-yy      sig-zz      sig-xy      sig-yz      sig-zx       plastic
state                                                                                 strain
699425-     13
1- 16 elastic   4.9281E-01  5.9754E-02  0.0000E+00 -2.7210E-02  1.4192E-02  1.2603E-01    1.7112E-02
2- 16 elastic   4.6965E-01  4.8664E-02  0.0000E+00 -2.1255E-02  1.4192E-02  1.2603E-01    1.2814E-02
3- 16 elastic   4.3029E-01  2.6264E-02  0.0000E+00 -7.2280E-03  1.4192E-02  1.2603E-01    7.1400E-03
4- 16 elastic   3.1283E-01 -1.4079E-02  0.0000E+00  1.3315E-02  1.4192E-02  1.2603E-01    1.9514E-03
5- 16 elastic  -3.4911E-01 -2.9740E-02  0.0000E+00  3.7036E-02  1.4192E-02  1.2603E-01    7.5132E-04
6- 16 elastic  -4.5764E-01 -7.0891E-02  0.0000E+00  3.6667E-02  1.4192E-02  1.2603E-01    7.1070E-03
7- 16 elastic  -4.8788E-01 -8.1926E-02  0.0000E+00  4.1023E-02  1.4192E-02  1.2603E-01    1.1321E-02
699426-     13
1- 16 elastic   3.5073E-01  6.2039E-03  0.0000E+00 -9.4607E-02 -3.4023E-03 -2.4265E-02    1.4478E-02
2- 16 elastic   3.5540E-01  8.6871E-03  0.0000E+00 -7.2062E-02 -3.4023E-03 -2.4265E-02    1.0498E-02
3- 16 elastic   3.6224E-01  7.2871E-03  0.0000E+00 -3.5263E-02 -3.4023E-03 -2.4265E-02    6.1994E-03
4- 16 elastic   2.3782E-01 -1.7772E-02  0.0000E+00  5.9101E-03 -3.4023E-03 -2.4265E-02    1.6298E-03
5- 16 elastic  -2.3065E-01 -3.2565E-02  0.0000E+00  6.0890E-02 -3.4023E-03 -2.4265E-02    1.3029E-03
6- 16 elastic  -3.0923E-01 -3.0984E-02  0.0000E+00  9.0408E-02 -3.4023E-03 -2.4265E-02    5.3680E-03
7- 16 elastic  -3.3606E-01 -2.5992E-02  0.0000E+00  1.0568E-01 -3.4023E-03 -2.4265E-02    9.3878E-03

Единственное отличие состоит в том, что в этом выводе мы имеем 16 вместо 2 вместо чисел от 1 до 7.

Пожалуйста, предложите мне исправление.

Ответы [ 5 ]

2 голосов
/ 22 февраля 2012

Это может работать для вас:

sed '/^\([0-9]\{7\}\).*/,+7!d;//{s//\1/;h;d};s/.* //;G;s/^\(.*\)\n\(.*\)/\2 \1/' file |
sort -g |
sed 'h;N;N;N;N;N;N;s/.*\n//;H;g;s/\n\S*//'
1346995 7.3682E-02 7.4616E-02
1346996 7.3999E-02 7.4362E-02

РЕДАКТИРОВАТЬ:

Со ссылкой на комментарии ниже и запрашиваемые результаты показаны в измененном вопросе, вот исправленное решение:

sed '/^\([0-9]\{7\}-\)\s*\([0-9]*\).*/,+7!d;//{s//at \1\2/;h;d};s/.* //;G;s/\n/ /' file| 
sort -g | 
sed '1s/^/min=/p;$s/^/max=/p;d'
min=7.3682E-02 at 1346995-25
max=7.4616E-02 at 1346995-25
1 голос
/ 22 февраля 2012
#!/bin/bash   

cat - <<-EOD > testMinMaxData.txt
1346995-     25
1-  2 elastic   5.9309E-01 -1.0920E-02  0.0000E+00  2.4431E-04  2.3158E-03  1.0608E-03    7.4616E-02
2-  2 elastic   6.1335E-01 -9.1746E-03  0.0000E+00 -4.2870E-04  2.3158E-03  1.0608E-03    7.4089E-02
3-  2 elastic   6.4586E-01 -7.3146E-03  0.0000E+00 -1.2961E-03  2.3158E-03  1.0608E-03    7.3794E-02
4-  2 elastic   6.7056E-01 -1.5564E-03  0.0000E+00 -1.0469E-03  2.3158E-03  1.0608E-03    7.3682E-02
5-  2 elastic   6.7493E-01  7.1420E-03  0.0000E+00  1.7934E-03  2.3158E-03  1.0608E-03    7.3708E-02
6-  2 elastic   6.7828E-01  1.4787E-02  0.0000E+00  5.4871E-03  2.3158E-03  1.0608E-03    7.3825E-02
7-  2 elastic   6.8092E-01  1.9656E-02  0.0000E+00  8.2580E-03  2.3158E-03  1.0608E-03    7.4210E-02
1346996-     25
1-  2 elastic   6.0586E-01 -4.6476E-03  0.0000E+00  9.4464E-03 -1.9585E-03 -5.1396E-03    7.4299E-02
2-  2 elastic   6.2548E-01 -5.1646E-03  0.0000E+00  6.3450E-03 -1.9585E-03 -5.1396E-03    7.4147E-02
3-  2 elastic   6.5631E-01 -5.3780E-03  0.0000E+00  1.1554E-03 -1.9585E-03 -5.1396E-03    7.4000E-02
4-  2 elastic   6.7186E-01 -1.5611E-03  0.0000E+00 -3.7045E-03 -1.9585E-03 -5.1396E-03    7.3999E-02
5-  2 elastic   6.7481E-01  5.1501E-03  0.0000E+00 -7.2939E-03 -1.9585E-03 -5.1396E-03    7.4107E-02
6-  2 elastic   6.7769E-01  1.1733E-02  0.0000E+00 -1.0146E-02 -1.9585E-03 -5.1396E-03    7.4238E-02
EOD

if ${testingMode:-true} ; then
  set -- testMinMaxData.txt
fi

awk '
   NF==2{gsub(/[  ]*/,"",$0); header=$0}
   NF==10{print header "\t" $10}
' "${@:?Usage:$0 file1 [file2 ....]}" \
| awk '{
    hd=$1
    if (! (hd in hdrs)) {
      hdrs[hd]=++i ; hdrsVal[i]=hd; min[hd]=999999; max[hd]=0.000000009 ;
      #dbg print "#dbg:added " hd " to hdrs"
    }
    #dbg print "#dbg:$2=" $2 "\tmin["hd"]=" min[hd] "\tmax["hd"]="max[hd]
    if ($2 < min[hd]) {
      min[hd]=$2
      #dbg print "#dbg:added "$2" to min["hd"]"
    }
    if ($2 > max[hd]+0.0) {
      max[hd]=$2
      #dbg print "#dbg:added "$2" to max["hd"]"
    }
}
END {
   #dbg for (x in hdrs) print "hdrs["x"]=" hdrs[x]
    for (j=1;j<=i;j++) {
      print hdrsVal[j] "\t" min[hdrsVal[j]] "\t" max[hdrsVal[j]]
    }
  }
'\
| awk 'BEGIN{
  minVal=9999999999
  maxVal=.000000009
  }
  {
    if ($2 < minVal) {
        minVal=$2 ; minTag=$1
        #dbg print "#dbg:added "$2" to min["hd"]"
    }
    if ($3 > maxVal) {
        maxVal=$3  ; maxTag=$1
        #dbg print "#dbg:added "$2" to max["hd"]"
    }
  }
  END {
   print "min=" minVal " at " minTag
   print "max=" maxVal " at " maxTag
  }
'

output

min=7.3682E-02 at 1346995-25
max=7.4616E-02 at 1346995-25

Этот сценарий представляет собой автономный набор тестов для проверки концепции.Для реального использования я бы порекомендовал удалить оба из следующих «блоков» кода и оставить только 3 awks в вашем рабочем файле сценария.

Блок cat ... > testMin...EOD создает ваши данные примера в тестовом файле.

Блок if ${testingMode:-true}... использует функцию оболочки set -- arg1 arg2 ... для установки позиционных параметров.Затем это значение раскрывается как параметр оболочки "$ {@}", который вы видите в конце первой программы awk (непосредственно перед символом канала ('|')).

Я также включил оценку использования в оценку "${@?Usage:$0 file1 [file2 ...]}".Если имена файлов не указаны, скрипт выдаст вам простое сообщение об ошибке / использовании.

Я оставил операторы отладки, вы можете удалить символ '#' впереди, чтобы увидеть, как обрабатываются данные при его обработке.проходит через скрипт.

Обратите внимание, что ассоциативные массивы awk hdrs[hd]=++i ; hdrsVal[i]=hd; и т. д. не всегда интуитивно очевидны для нового пользователя awk.НО awk ассоциативные массивы - одна из самых мощных функций языка.Они определенно стоят вашего времени на эксперименты, чтобы понять, как они работают.Включите некоторые строки отладки, чтобы увидеть, где какие значения сортируются.

Единственная причина, по которой я сохраняю arr hdrs[hd], заключается в том, что в конце мы можем перечислять через массив с помощью числового ключа (1,2,3, ...) это означает, что данные будут напечатаны в том порядке, в котором они были прочитаны, и, используя значение, возвращаемое hdrs[2]=1346995-25, мы можем искать минимальное и максимальное значения через min [1346995-25],max [1346995-25].

Наконец, поскольку ваши данные выглядят как технические данные, вы можете найти дополнительную помощь, посмотрев ссылки на awk.info - Engineering

Правка

Я добавил окончательную дистилляцию всего к 1 минуте и к максимальному значению с помощью setID.

Вы написали

КакМогу ли я добавить имя входного файла и имя выходного файла.

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

Затем из командной строки Unix / Linux / Cygwin вам нужно «пометить»файл, чтобы ОС знала, что он должен быть исполняемым.

chmod 755 ./myMinMaxFinder.sh

Теперь вы можете выполнить cmd следующим образом:

 ./myMinMaxFinder.sh file1 [file2 .... filen] > myOUTPUT.FILE

Это стандартный способ создания выходных файлов в Unix.,Обработка аргументов будет платой за консультацию; -)

Я упоминал awk.info выше.Поскольку вы инженер-механик, обязательно ознакомьтесь с

http://awk.info/?doc/mecheng.html

Это также указывает на другой веб-сайт, выполненный инженером-механиком

http://www.tikmark.com/awkeng/awkscripts.html

Дизайн, который я здесь используюэто традиционный Unix-конвейер.Каждый раздел awk решает одну часть головоломки.Вы можете отключить любой раздел (вставив 2 пустые строки и добавив exit, чтобы увидеть, что делает каждый этап скрипта.

Для получения более общей информации об использовании awk, см. Этот самый превосходный GrymoireAwk Tutorial

Надеюсь, это поможет.

1 голос
/ 22 февраля 2012

rrr ... не могу вставить блок кода в комментарии = (если я правильно понял, вам нужны цифры из первого столбца, которые соответствуют минимальным и максимальным значениям из 10-го столбца, верно? Чем вы можете использовать следующий скрипт:

#!/bin/bash
minAndMax="`cat Plastic.k | awk '{ print $10 }' | sed -ne'/^[0-9]\{1\}/p' | sort -g | sed -n -e'1p' -e'$p'`"
min="`echo \"$minAndMax\" | head -n 1`"
max="`echo \"$minAndMax\" | tail -n 1`"
minIDs="`cat Plastic.k | awk \"\\\$10 == $min { print \\\$1 }\" | sed -e's/-$//'`"
maxIDs="`cat Plastic.k | awk \"\\\$10 == $max { print \\\$1 }\" | sed -e's/-$//'`"
echo "\$minIDs==$minIDs"
echo "\$maxIDs==$maxIDs"
1 голос
/ 22 февраля 2012
$ cat input.txt | awk 'NR<4{next}; NF==2{id=$1}; NF==10{printf "%s %f\n",id+0,$10}' | sort -k1,1 -k2,2n | awk 'x!=$1{if(NR!=1)printf "%s\n\n",y;x=$1;print};{y=$0};END{print}'

Разбить на несколько строк: (> это приглашение bash):

$ cat input.txt |
> awk 'NR<4{next}; NF==2{id=$1}; NF==10{printf "%s %f\n",id+0,$10}' |
> sort -k1,1 -k2,2n |
> awk 'x!=$1{if(NR!=1)printf "%s\n\n",y;x=$1;print};{y=$0};END{print}'

Результат:

1346995 0.073682
1346995 0.074616

1346996 0.073999
1346996 0.074362

Пояснение:

  • NR<4{next} пропустить первые 3 строки
  • NF==2{id=$1} отслеживать идентификатор текущей группы
  • NF==10{printf...$10} вывести идентификатор и значение столбца # 10
  • sort -k1,1 -k2,2n сортировка по столбцу № 1 и столбцу № 2
  • awk 'x!=$1...print} распечатать последнюю строку последней группы перед печатью первой строки текущей группы
  • {y=$0} отслеживать последнюю строку
  • END{print} печать последней строки
1 голос
/ 22 февраля 2012

вот решение: Сортировка научного номера с сортировкой Unix так что используйте это:

cat Plastic.k | awk '{ print $10 }' | sed -ne'/^[0-9]\{1\}/p' | sort -g | sed -n -e'1p' -e'$p'
...