Вопрос по команде awk

Тема в разделе "WASM.UNIX", создана пользователем Imeiko, 31 июл 2017.

  1. Imeiko

    Imeiko New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    4
    Здравствуйте, имею строку с различными разделителями между столбцов ("\t" ";" ":" "~" и др.). Мне необходимо выбрать столбец содержащий 9 символов, переместить его в начало строки и распечатать измененную строку.
    Помогите решить проблему.
    Спасибо
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.329
    man awk
     
  3. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    В цикле распарсь эту строку. сохрани часть подстроки в новую переменную А , за исключением той которая содержит 9 символов, строку с 9 символами в строку Б.
    По окончании создаешь переменная С = Б + А.
    Печатаешь переменную С. Это простой программстский подход. Можно и командами как рмн говорит, но это нужно быть экспертом в области использования баш скриптов, предполагает высокий порог. Подход который предлагаю я простой и понятный.
     
  4. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    Вот начальный код, всю работу за тебя делать не буду, дальше я думаю тривиально:
    string="john is 17 years old"
    IFS=' '
    for word in $string
    do
    size=${#word}
    echo "$size"
    echo "$word"
    done
    Ну и конечно, все разделители замни на пробел, либо добавь к разделителям пробел, потом
    уберешь. Либо awk, если осилишь. Я не вижу нужды изучать команду, которая потребуется мне раз в жизни.
     
  5. Imeiko

    Imeiko New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    4
    Я примерно так и делала, но столкнулась с проблемой, что мой столбец с 9ю символами стоит не обязательно №5.
    А проблема заключается в том, что столбец может быть в 1й строке 3й, а в 30й строке 5й, и разделители до и после могут быть разные. С разделителями понятно, можно все разделители привести к одному виду (пробелы нельзя, после удаления пробелов склеится информация в столбцах).
    Но задача поставить столбец содержащий 9ть символов вначале строки и желательно чтобы разделители сохранились те которые были. У этого столбца уникальность только то, что только в нем ровно 9ть символов. До него 1 вид разделителя после него может быть другой.
    Я себе представляю примерно так структуру команды:
    1. в awk определяем вид разделителей в файле (чтобы команда понимала между какими точками искать, скорее всего необходимо подключить сабфайл с перечисленными разделителями)
    2. ищем столбец длиной 9 символов (if (length == 9))
    3. Печатаем новый файл с перенесенным столбцом (print $i ";" $0) (Не 0 конечно но как-то мол остальные столбцы (чтобы структура строки с разделителями сохранилась))
    Скорее всего, что в одну команду не получится собрать.
    Помогите пожалуйста.
     
  6. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    Imeiko, Я дал пример, которые решит все описанные проблемы. Вся исчерпывающая программа уже почти есть.
    Запусти вот это и посмотри все внимательно и ставь мне лайк, а то некоторые думают я зря копчу воздух тут.
    string="john is 17 years this-is-9"
    probel=" "
    half_string=""
    final_string=""
    nine_str=""
    IFS=' '
    for word in $string
    do
    size=${#word}
    if [ $size -eq 9 ]
    then
    echo "Count is 9 lets save it in variable..."
    nine_str=$word
    else
    echo "this word is not 9 length."
    half_string=$half_string$word$probel
    fi
    #echo "$size"
    #echo "$word"
    done
    final_string=$nine_str$probel$half_string
    echo "$final_string"

    Как видишь слово "this-is-9" в котором 9 символов теперь на первом месте.
     
    Imeiko нравится это.
  7. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    Разделители у тебя и сохранятся, нужно только к твоим разделителям прибавить пробел, затем распарсить строку и после этого можно пробелы убирать, если не нужны. Скрип можно и запустить одной командой. Думаю программа исчерпывающая. Уж к разделителям добавить пробел ты можешь. Если нет, то тогда i rest my case.
    awk это почти язык программирования. рмн пошутил. Да разумется программа получится несколько длинней, но в ней несколько другая философия и разные подход, которые может пригодится в будущем для решения таких проблем.
     
  8. Imeiko

    Imeiko New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    4
    Спасибо конечно большое. А если у меня 1000 строк как мне быть, в смысле как мне применить данную обработку ко всему файлу?
     
  9. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    просто, ты пишешь другой сценарий и в цикле каждой строки вызываешь мой сценарий.
    Например так
    #!/bin/bash
    cat peptides.txt | while read line
    do
    # do something with $line here
    myscript.sh $line #эту строку уже передаешь скрипту которые обрабатывает
    done
    файл peptieds.txt и есть твой файл в котором, 1000 строк. Ну а awk это факутальтивно уже изучаешь, если время девать некуда. Мой подход конечно брутфорс, но я все скрипты достаточно быстро решают таким способом, потому что он раскладывает проблему на простейшие и уже отдельно решает каждую задачу.
     
    Imeiko нравится это.
  10. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    чтобы знать тонкости awk и много других замечательных команд в линух, это надо немало часов чахнуть над ними. Я стороник low hanging fruit.
    Заталкиваешь потом эти два скрипта в папку bin и сможешь юзать с командной строке, либо создаешь свою папку скриптов и в переменной окружения добавляешь путь к своей папке.
     
  11. Imeiko

    Imeiko New Member

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    4
    Я правильно понимаю
    Создаю скрипт например filestart.sh:
    И второй скрипт line.sh:
    И должно работать? Только вот как мне потом вывести измененнный файл в новый файл?
     
  12. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    нет.
    #!/bin/bash
    string=$1
     
  13. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    для этого нужно в гугле ввести
    bash script return value
    а также
    bash script write to file
     
  14. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
  15. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    по возврату строки из первого скрипта
    https://stackoverflow.com/questions/16338086/bash-return-value-from-subscript-to-parent-script
    # Child (for example: 'child_script')
    exit 42
    # Parent
    child_script
    retn_code=$?
    If you wish to return a text string, then you will have to do that through stdout (or a file). There are several ways of capturing that, the simplest is:
    # Child (for example: 'child_script')
    echo "some text value"

    # Parent
    retn_value=$(child_script)
     
  16. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    неверный вопрос. Ответ в запуске, дебаге и проверке, что на экране. Учись сама ловить рыбу, тогда не будушь ходить голодной.
     
  17. neutronion_old_school

    neutronion_old_school Попугай Сильвера

    Публикаций:
    0
    Регистрация:
    23 июл 2017
    Сообщения:
    411
    Имей ввиду, в моем скрипте есть одна тонкость(баг), если у тебя два слова размером в 9 символов, то первое слово исчезнет и появится только второе.
    Если у тебя три слова в 9 символов, то тогда у тебя исчезнет два слова и останется последнее и т.д. Думаю это очевидно. Немного brain work, и эта проблема
    легко решается в скрипте. Подсказка, это решается введением еще одной переменной-флагом.
    которая будет учитывать, было ли уже слово в 9 символов сохранено. Либо сохраняй второе слово в 9 символов в ту же переменную соединяя их пробелом. Тогда у тебя будут идти в строке в новом файле первыми только слова в 9 символов.
     
  18. Minzdrav

    Minzdrav Well-Known Member

    Публикаций:
    0
    Регистрация:
    21 мар 2017
    Сообщения:
    1.082
    ДЕЛАЛА аху_ть...
    У него женские мозги.