Вы можете сделать это с помощью команды перевода:
jent=$(echo "$d" | tr -ds UTC " " | tr " ",)
# the first double quotes contains two spaces
echo "$jent"
Mon,Apr,22,05:06:00,2019
Проблема в том, что вы пытаетесь явно добиться двух вещей, которые, тем не менее, подразумевают друг друга:
user1
#
или;
)Однако ваше второе регулярное выражение гласит: «Строка должна начинаться с любого символа, отличного от #
или ;
, а затем содержать user1
. Итак, grep
ожидает, что перед user1
есть символ. ] Это не проблема в первом регулярном выражении, где вы требуете «любой символ, который не является #
или ;
, за которым следует ser1
», поскольку user1
начинается с символа, который не является #
или ;
.
Если вы уверены, что строка начинается с user1
, вы можете просто использовать
grep -P '^user1 etc.'
или, если могут быть пробелы,
grep -P '^ *user1 etc.'
Вы привязываете регулярное выражение к началу строки:
^[^#;]ser1
Это означает, что «соответствуют строки, начинающиеся с любого символа, отличного от #
или ;
, а затем строка ser1
. Таким образом, [^#;]
соответствует u
из user1
. Если вы хотите дать слово целиком, нужно искать строки, начинающиеся с user1
непосредственно:
^user1
В качестве альтернативы можно разрешить 0 вхождений шаблона [^#;]
:
^[^#;]*ser1
Таким образом, ваша полная команда может быть такой:
grep -P '(^user1.*ALL=\(ALL\) NOPASSWD.*\/app\/tomcat.*$)' test.txt
или
grep -P '(^[^#;]*user1.*ALL=\(ALL\) NOPASSWD.*\/app\/tomcat.*$)' test.txt
Однако это кажется очень, очень сложным. Все, что вам действительно нужно, это:
grep -P '^[^#;]*user1'
в этом примере.