Intereting Posts
Как показать номера строк в vim в правой части буфера? последовательный порт для мониторинга экрана Я хочу статический IP-адрес для моего (сетевого или компьютерного)? Проблема установки Fedora 23 в VM с использованием KVM на Linux Mint 17.2 Другой способ замены новых строк вместо использования tr Удалите и замените две конкретные строки с помощью команды sed iostat: что такое концепция слияния Что такое файлы журналов Tomcat? Невозможно мостик двух стыковых интерфейсов – совет? Не могу выйти из X! Почему нельзя использовать `su` для переключения на пользователей с пустым паролем? Как создать реальную копию дескриптора файла stdout и stderr без использования unbuffer / script / tee только с встроенными встроенными в bash? Обработка каждой строки из текстового файла и удаление связанных файлов с диска Есть ли способ найти файл в обратном рекурсивном поиске? unix: заменить один полный столбец в одном файле одним значением из другого файла

Ограничение строк max и min length

У меня есть этот вход:

XX3083136|bla-bla texthere texttt|asfdasfd@safdsadf.com|SADFdsafsafd|ASDfasfdsafd|DSFSAFD|dsafasfd|sadfsad| XX3083372|bla-bla-bla this is a text bla-bla|asdfsfda@lsadfasfdda.com|SDFsafas|SADFsa|DFSsdf|asdasdf|sadfdsafsaf|asdfsadf| 

и мне нужен этот вывод:

 XX3083136|bla-bla texthere textt|asfdasfd@safdsadf.com |SADFdsafsafd|ASDfasfdsafd|DSFSAFD|dsafasfd|sadfsad| XX3083372|bla-bla-bla this is a te|asdfsfda@lsadfasfdda.com |SDFsafas|SADFsa|DFSsdf|asdasdf|sadfdsafsaf|asdfsadf| 

Поэтому разница в том, что мне нужно контролировать максимальную длину текста между «|». Если он короче, то заданная длина линии, тогда «» нужно поместить. В этом примере вторая строка ограничена максимум 24 символами, а третья строка должна быть не менее 30 символов. Для разных строк потребуются разные максимальные / минимальные пределы.

Как я могу это сделать в bash?

Дополнить немного:

Основной формат для printf в тексте:

 %s # Print as is %10 # Right justify minimum width print 10 %-10 # Left justify minimum width print 10 %.10 # Max width 10 %10.10 # Max width 10, min width print 10 %-10.10 # Left justify, max width 10, min width print 10 %*s # Same as above, but get number from arguments %-*s # Same as above, but get number from arguments ... 

Когда вы получаете длинные узоры, он может стать немного беспорядочным, чтобы отслеживать, где и где и т. Д. Один из способов сделать это немного проще, может быть примерно так:

 #!/bin/bash usage() { printf "Usage: %s <FILE>\n" "$(basename "$0")" >&2 [[ -n "$1" ]] && echo "$1" exit 1 } if [[ ! -t 0 ]]; then : # Piped to elif [[ $# -eq 0 ]]; then usage "Missing file." elif [[ ! -r "$1" ]]; then usage "Unable to read \`$1'." else # Accept input from file to file descriptor 0, aka stdin exec 0< "$1" fi fmt="" fmt="$fmt%s|" # F1 fmt="$fmt%-24.24s|" # F2 fmt="$fmt%-30s|" # F3 fmt="$fmt%-10.10s|" # F4 fmt="$fmt%-10.10s|" # F5 fmt="$fmt%-10s|" # F6 fmt="$fmt%-2.2s|" # F7 fmt="$fmt%-2.2s|\n" # F8 # Set IFS to newline and bar and read fields # assigning them to f1 ... f8 # while IFS=$'\n'"|" read f1 f2 f3 f4 f5 f6 f7 f8; do printf "$fmt"\ "$f1" "$f2" "$f3" "$f4" \ "$f5" "$f6" "$f7" "$f8" done <&0 

Или. например:

 while IFS=$'\n'"|" read f1 f2 f3 f4 f5 f6 f7 f8; do printf "%s|%-*.*s|%-*s\n" \ "$f1" \ 24 24 "$f2" \ 30 "$f3" done < "input" 

Если это только разбор строки, awk – хорошая альтернатива. например:

 #!/usr/bin/awk -f BEGIN {FS="|"} /^/ { printf "%s|%-24.24s|%-30s|%-10.10s|%-10.10s|%-10s\n", $1, $2, $3, $4, $5, $6 } 

Или:

 #!/usr/bin/awk -f BEGIN { FS="|" } /^/ { printf "%s|%-*.*s|%-*s|%-*.*s|%-*.*s|%-*s\n", $1, 24, 24, $2, 30, $3, 10, 10, $4, 10, 10, $5, 10, $6 } 

Вы можете играть вокруг встроенного printf чтобы вырезать строку:

 $ printf '%.2s\n' 'azerty' az 

И используя его, чтобы положить разделитель | где вы хотите, например:

 $ printf '%10s%10s%10s%10s%10s%10s\n' '|' '|' '|' '|' '|' '|' | | | | | | 

См. http://www.bash-hackers.org/wiki/doku.php/commands/builtin/printf