Friday, 15 December 2017

Ubuntu on WSL piping output to the host OS's drives - convert LFs to CRLFs

So continuing on the Ubuntu theme. I need to configure Apache. So I am not used to Linux because it has been a dozen years ago since I trained for certification on Linux. I still want to use my favourite Windows apps not mention the windowed environment; it takes a while to acclimatise to console culture. Specifically, whilst poking around the Linux file system, I need to find a way to pipe output of a command to a file on the host OS’s drive and then handle the line feed issue.

In Linux line feeds are one character ASC 10, whilst in Windows line feeds are in fact two, ASC 13 + ASC 10. If you don’t believe me then in VBA Immediate window try ?ASC(MID$(vbNewLine,1,1)) and then ?ASC(MID$(vbNewLine,2,1)) .

So in the Linux console a typical command would be sudo find / -name apache2.conf &> /mnt/n/findapache.txt which searches for Apache2 configuration file (it’s not where my Apache book says it should be!). The above command pipes output both stdout and stderr (hence “&>”) to /mnt/n which is where my N: drive is mounted into the unified Linux file system.

So here is some code to process the line feeds


Option Explicit

'* Tools->References->Microsoft Scripting Runtime

Sub Test()
    'ConvertLinuxLineFeedsToWindowsCRAndLineFeeds "n:\findapache.txt"
    ConvertLinuxLineFeedsToWindowsCRAndLineFeeds "n:\apache2.conf"
End Sub

Sub ConvertLinuxLineFeedsToWindowsCRAndLineFeeds(ByVal sLinuxFile As String, _
                        Optional ByVal sWindowsFile As String)

    sWindowsFile = Trim(sWindowsFile)
    If LenB(sWindowsFile) = 0 Then
        Dim vSplit As Variant
        vSplit = VBA.Split(sLinuxFile, ".")
        
        Dim lCount As Long
        lCount = UBound(vSplit)
        ReDim Preserve vSplit(0 To lCount + 1)
        vSplit(lCount + 1) = vSplit(lCount)
        vSplit(lCount) = "winLfCr"
        
        sWindowsFile = VBA.Join(vSplit, ".")
    
    End If

    Dim oFSO As New Scripting.FileSystemObject
    
    
    Debug.Assert oFSO.FileExists(sLinuxFile)
    Dim oTxtIn As Scripting.TextStream
    Set oTxtIn = oFSO.OpenTextFile(sLinuxFile)

    Dim oTxtOut As Scripting.TextStream
    Set oTxtOut = oFSO.CreateTextFile(sWindowsFile)

    While Not oTxtIn.AtEndOfStream
        Dim sLine As String
        sLine = oTxtIn.ReadLine
        Debug.Print sLine
        
        oTxtOut.WriteLine sLine
        
    Wend
    
    oTxtOut.Close
    oTxtIn.Close
    
    Set oTxtOut = Nothing
    Set oTxtIn = Nothing

End Sub


Now one can use Notepad to view the contents. Without the windows line feeds the whole file looks like it has no line breaks!

No comments:

Post a Comment