Необходимо отформатировать CSV

Запускайте сторону чтения rsync как выделенный не -пользователь root, но с возможностью CAP_DAC_READ_SEARCH. Пользователь должен иметь полное представление о файловой системе (конечно )и доступ к копии /usr/bin/rsync, которая имеет эту возможность. Я не очень хорошо разбираюсь в возможностях Linux, но думаю, как это настроить:

cp /usr/bin/rsync /usr/local/sbin/rsync-for-backup
chown root.root /usr/local/sbin/rsync-for-backup
chmod 700 /usr/local/sbin/rsync-for-backup
setfacl -m user:backupuser:rx /usr/local/sbin/rsync-for-backup
setcap cap_dac_read_search+ep /usr/local/sbin/rsync-for-backup

Не забывайте обновлять копию при каждом обновлении rsync. Пройдите --rsync-path=/usr/local/sbin/rsync-for-backupна другую сторону.

(Я предполагаю Linux. Для других вариантов Unix потребуются другие решения.)


Некоторые другие потенциальные подходы:

  • Решение bindfs изhttps://unix.stackexchange.com/a/91522позволяло читать содержимое файла, но искажало некоторые метаданные. Я не уверен навскидку, есть ли способ заставить это работать для резервных копий.
  • Запуск от имени пользователя root, но с ограничительными правилами SELinux должен помочь, но не спрашивайте меня, какими должны быть эти правила.

1
09.11.2021, 10:55
3 ответа

Я пришел с sedрешением

sed -e 's/,"""/,"/g' -e 's/""",/",/g' -e 's/\([^,]\)""/\1/g' -e 's/""\([^,]\)/\1/' 

, что дает

"Basic","40","[40]","13F","[13F]","",""
"Basic","0","[0]","","","MCOMB","[MCOMB]"
"Basic","21,21","[21,21]","","","","",""

Команда sed довольно проста

  • 's/,"""/,"/g'заменить ,"""на ,"для всех случаевg
  • 's/\([^,]\)""/\1/g'найдите любой не запятый char [^,]и два ", запомните char \( \)и замените на char запомненный\1

обратите внимание, что пробел в конце строки удалит последний""

как указал @cas, в долгосрочной перспективе было бы лучше использовать инструмент csv.

0
09.11.2021, 12:07

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

Использование csvformatиз csvkit и trдля удаления внутренних кавычек в каждом поле:

$ cat file
"Basic","""40""","[""40""]","""13F""","[""13F""]","",""
"Basic","""0""","[""0""]","","","""MCOMB""","[""MCOMB""]"
"Basic","""21,21""","[""21"",""21""]","","","","",""
$ csvformat -Q "'" file | tr -d '"' | csvformat -q "'"
Basic,40,[40],13F,[13F],,
Basic,0,[0],,,MCOMB,[MCOMB]
Basic,"21,21","[21,21]",,,,,

Приведенный выше конвейер сначала меняет символ кавычек, используемый в CSV-файле, с двойных кавычек на одинарные. Команда trудаляет все оставшиеся двойные кавычки (части данных ). Последняя команда csvformatпреобразует данные обратно в двойные кавычки для цитирования.

Если вам нужно каждое указанное в кавычках поле, даже пустое, добавьте -U 1ко второму вызову csvformat. Утилиты csvkit по умолчанию выводят кавычки только для тех полей, которые в этом нуждаются.

0
09.11.2021, 13:49

Вам нужно изучить инструмент, поддерживающий CSV -. Как вы уже видели, вы можете написать очень сложный awk и sed ивсе равноошибиться. @cas упомянул miller и csvkit, я их не использовал, поэтому не могу сказать, могут ли они делать то, что вам нужно.

Я использую GoCSV , очень простой инструмент с набором команд, которые помогут вам достичь цели.

Взяв эту строку отдельно, первое, что нужно GoCSV, — это заголовок, поэтому я передам эту строку в его команду cap , чтобы создать фиктивный заголовок с именем по умолчанию «Col».:

echo '"Basic","""21,21""","[""21"",""21""]","","","","",""' | \
gocsv cap --default-name Col

и я получаю:

Col 1,Col 2,Col 3,Col 4,Col 5,Col 6,Col 7,Col 8
Basic,"""21,21""","[""21"",""21""]",,,,,

('Col' был добавлен с уникальными порядковыми номерами для каждого столбца)

Вы можете видеть, что команда удалила ненужные пустые кавычки в конце. Теперь о процитированных цитатах.

Я возьму этот вывод и направлю его в команду replace , где я могу указать шаблон регулярного выражения для поиска, "и замену пустой строки:

echo '"Basic","""21,21""","[""21"",""21""]","","","","",""' | \                                                                  
gocsv cap --default-name Col | \                                   
gocsv replace --regex '"' --repl ''

и я получаю:

Col 1,Col 2,Col 3,Col 4,Col 5,Col 6,Col 7,Col 8
Basic,"21,21","[21,21]",,,,,

Если вам нужно убрать заголовок, передайте его в behead . Вот полный конвейер:

echo '"Basic","""21,21""","[""21"",""21""]","","","","",""' | \
gocsv cap --default-name Col | \
gocsv replace --regex '"' --repl '' | \
gocsv behead
Basic,"21,21","[21,21]",,,,,
1
12.11.2021, 08:11

Теги

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