1

To make my script a bit more readable I'm trying to split my long grep pattern. Is that possible?

Example, in by bash script, instead of this long line

smartctl -a /dev/sda | grep -Ei "Spin_Retry_Count|Calibration_Retry_Count|Reallocated_Event_Count|Offline_Uncorrectable|Reallocated_Sector_Ct|Current_Pending_Sector|CRC_Error_Count|Multi_Zone_Error_Rate|Temperature|CRC_Error_Count|Runtime_Bad_Block|Erase_Fail_Count|Program_Fail_C|End-to-End_Error" | awk '{print $2" "$10}')

I want to split into something like that, to make things more readable

smartctl -a /dev/sda | grep -Ei "Spin_Retry_Count|"\
                                   "Calibration_Retry_Count|"\
                                   "Reallocated_Event_Count|"\
                                   "Offline_Uncorrectable|"\
                                   "Reallocated_Sector_Ct|"\
                                   "Current_Pending_Sector|"\
                                   "CRC_Error_Count|"\
                                   "Multi_Zone_Error_Rate|"\
                                   "Temperature|"\
                                   "CRC_Error_Count|"\
                                   "Runtime_Bad_Block|"\
                                   "Erase_Fail_Count|"\
                                   "Program_Fail_C|"\
                                   "End-to-End_Error" | awk '{print $2" "$10}')
  • could you provide more details? what exactly are you trying to achieve? – Bart Jun 28 at 11:20
2

The sequence "backslash-newline-whitespace" is replaced by a single space, so you are adding spaces into the pattern.

Using bash arrays can lead to readable code, something like this:

words=(
    "Spin_Retry_Count"
    "Calibration_Retry_Count"
    "Reallocated_Event_Count"
    "Offline_Uncorrectable"
    "Reallocated_Sector_Ct"
    "Current_Pending_Sector"
    "CRC_Error_Count"
    "Multi_Zone_Error_Rate"
    "Temperature"
    "CRC_Error_Count"
    "Runtime_Bad_Block"
    "Erase_Fail_Count"
    "Program_Fail_C"
    "End-to-End_Error"
)
# join the words with pipes
pattern=$( IFS='|'; echo "${words[*]}" )

smartctl -a /dev/sda | grep -Ei "$pattern" | awk '{print $2, $10}'

We can remove grep from the pipeline because GNU awk can do what grep does, but perhaps a little wordier:

smartctl -a /dev/sda | gawk -v p="$pattern" -v IGNORECASE=1 '$0 ~ p {print $2, $10}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.