Как изменить столбцы, убрать кавычки и добавить табуляцию в текстовый файл с помощью bash

for i in `cat file2|wc -l`  
do  
   j=`cat  file1|cut -d, -f4`  
   m=`cat  file2|cut -d, -f5`  
   file1_dom=`cat  file1|cut -d, -f1`  
   file2_vm=`cat  file2|cut -d, -f2`  
        if [[ `${j} -gt ${m}` ]]  
        then  
             echo ${file2_vm} can be reclocated to ${file1_dom}  
        fi  
done    

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

  • Не используйте обратные кавычки для запуска оболочки sub -, они уже давно объявлены устаревшими. Предпочитайте синтаксис $(cmd).
  • Нет необходимости писать cat file2 | wc -l, например, wc -l file2короче и эффективнее. (Нет необходимости запускать cat, передавать его stdoutна wcи т. д.)
  • Вы должны всегда, всегда, всегда заключать в кавычки все подстановки переменных, если вы не хотите, чтобы они подвергались разбиению на слова и подстановке. Я имею в виду unqouted ${file1_dom}. Кроме того, нет необходимости писать ${file1_dom}, было бы предпочтительнее $file1_dom(синтаксис ${...} предлагает некоторые другие преимущества, которые здесь не нужны ).
  • Точно так же вы всегда должны предотвращать распространенные ошибки сценариев, добавляя -euв строку интерпретатора (shebang )ваших сценариев.
  • Вам не нужно использовать [[для простых числовых сравнений, достаточно [.
  • Ошибка, вероятно, заключается в том, что сравнение:${j} -gt ${m}окружено обратными кавычками и, следовательно, выполняется в подоболочке, поэтому значение jпринимается в качестве имени команды. (Вот откуда пришло сообщение. )Вы хотите что-то вроде if [ "$j" -gt "$m" ]; then..., применяя все вышеперечисленные правила.

Если вы решите переписать свой сценарий в соответствии с этими правилами, добавьте его в свой исходный пост, чтобы другие могли извлечь пользу из того, что правильный сценарий имеет значение.

0
09.12.2020, 21:40
2 ответа

С csvcutиз csvkit и Miller на основе Python -:

$ csvcut -S -c Name,Year,Age,Movie file.csv | 
     mlr --icsv --opprint sort -f Name then rename Name,Actor,Movie,Film
Actor            Year Age Film
Emil Jannings    1928 44  The Last Command, The Way of All Flesh
George Arliss    1930 62  Disraeli
Lionel Barrymore 1931 53  A Free Soul
Warner Baxter    1929 41  In Old Arizona

Хотя я думаю, что Миллер должен быть в состоянии сделать это сам по себе, он, кажется, неправильно -анализирует разделитель в кавычках, когда он не является одним символом.

1
18.03.2021, 22:43

С GNU awk для FPAT:

$ cat tst.awk
BEGIN {
    in2outTag["Name"]  = "Actor"
    in2outTag["Movie"] = "Film"
    numOutFlds = split("Actor Year Age Film",outTags)
    FPAT = "\\s*(([^,]*)|(\"[^\"]+\"))\\s*"
    OFS = "\t"
}

{
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        gsub(/^[[:space:]]*"?|"?[[:space:]]*$/,"",$inFldNr)
    }
}

NR == 1 {
    for (inFldNr=1; inFldNr<=NF; inFldNr++) {
        tag = ( $inFldNr in in2outTag ? in2outTag[$inFldNr] : $inFldNr )
        tag2inNr[tag] = inFldNr
    }

    printf "%d%s", 0, OFS
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        tag = outTags[outFldNr]
        out2inNr[outFldNr] = tag2inNr[tag]
        printf "%s%s", tag, (outFldNr < numOutFlds ? OFS : ORS)
    }
    next
}

{
    printf "%d%s", 1, OFS
    for (outFldNr=1; outFldNr<=numOutFlds; outFldNr++) {
        inFldNr = out2inNr[outFldNr]
        val = $inFldNr
        printf "%s%s", val, (outFldNr < numOutFlds ? OFS : ORS)
    }
}

$ awk -f tst.awk file | sort -t$'\t' -k1,1n -k2,2 | cut -f2-
Actor   Year    Age     Film
Emil Jannings   1928    44      The Last Command, The Way of All Flesh
George Arliss   1930    62      Disraeli
Lionel Barrymore        1931    53      A Free Soul
Warner Baxter   1929    41      In Old Arizona
0
18.03.2021, 22:43

Теги

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